package com.mac.sys.urtils;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

public class HttpUtils
{
    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url   发送请求的URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param)
    {
        String result = "";
        BufferedReader in = null;
        try
        {
            if (param != null)
            {
                url = url + "?" + param;
            }
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet())
            {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null)
            {
                result += line;
            }
        } catch (Exception e)
        {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
            } catch (Exception e2)
            {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * Created by daojia on 2017-6-20.
     * 模拟httpsend请求，传入的参数有url以及附带的参数,返回String类型
     */

    public static String send(String url,Map<String,Object> map)
    {
        String result = "";
        try
        {
            //创建httpclient对象
            CloseableHttpClient client = HttpClients.createDefault();
            //创建post请求对象
            HttpPost httpPost = new HttpPost(url);
            //装填参数
            List<BasicNameValuePair> parm = new ArrayList<BasicNameValuePair>();
            if (map != null)
            {
                for (Map.Entry<String, Object> me : map.entrySet())
                {
                    parm.add(new BasicNameValuePair(me.getKey(), String.valueOf(me.getValue())));
                }
            }

            System.out.println("请求参数" + parm.toString());


            httpPost.setEntity(new UrlEncodedFormEntity(parm, "utf-8"));

            System.out.println("请求链接" + httpPost.toString());

            //执行请求
            CloseableHttpResponse response = client.execute(httpPost);
            result = response.toString();
            System.out.println("请求链接" + result);
            response.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }


        return result;

    }
            /**
             * 向指定 URL 发送POST方法的请求
             *
             * @param url   发送请求的 URL
             * @param param 请求参数，请求参数格式 name1=value1&name2=value2 的形式。
             * @return 所代表远程资源的响应结果
             */
    public static String sendPost(String url, String param)
    {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try
        {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);

            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null)
            {
                result += line;
            }
        } catch (Exception e)
        {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            } catch (IOException ex)
            {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url  发送请求的 URL
     * @param json 请求参数，请求参数应该是 {key:value1, key:value2} 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, JSONObject json)
    {
        try
        {
            PostMethod postMethod = null;
            postMethod = new PostMethod(url);
            postMethod.setRequestHeader("Content-Type", "application/json;charset=utf-8");
            RequestEntity se = new StringRequestEntity(json.toString() ,"application/json" ,"UTF-8");

            postMethod.setRequestEntity(se);

            HttpClient httpClient = new HttpClient();
            int response = httpClient.executeMethod(postMethod); // 执行POST方法

            // 使用getResponseBodyAsStream()代替getResponseBodyAsString使用流的方式来接收,(原因：返回数据过长，超过1M)
            //String result = postMethod.getResponseBodyAsString();
            InputStream inputStream = postMethod.getResponseBodyAsStream();
            System.out.println("---------------post请求，获取inputSteam对象成功");

//            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder("");
//            String str = "";

//            while ((str = br.readLine()) != null) {
//                sb.append(str);
//            }
//            return sb.toString();


//            byte[] buffer = new byte[10240];
//            int readBytes = 0;
//            while((readBytes = inputStream.read(buffer)) > 0)
//            {
////                Thread.sleep(1);
//                sb.append(new String(buffer, 0, readBytes));
//            }
//            return sb.toString();

            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[10240];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            return result.toString("UTF-8");


        } catch (Exception e)
        {
            throw new RuntimeException(e.getMessage());
        }


    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url  发送请求的 URL
     * @param json 请求参数，请求参数应该是 {key:value1, key:value2} 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost2(String url, JSONObject json)
    {


        PrintWriter out = null;
        BufferedReader in = null;
        HttpURLConnection conn = null;
        StringBuilder sb = new StringBuilder("");
        String result = "";
        try
        {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            conn = (HttpURLConnection) realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("connection", "Keep-Alive");
//            conn.setRequestProperty("user-agent",
//                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setUseCaches(false);//设置不要缓存
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(json.toString());
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
//            in = new BufferedReader(
//                    new InputStreamReader(conn.getInputStream()));
//            String line;
//            while ((line = in.readLine()) != null)
//            {
//                sb.append(line);
//            }
            InputStream inputStream = conn.getInputStream();
            System.out.println("---------------post2请求，获取inputSteam对象成功");
//            byte[] buffer = new byte[10240];
//            int readBytes = 0;
//            while((readBytes = inputStream.read(buffer)) > 0)
//            {
//                sb.append(new String(buffer, 0, readBytes));
//            }
//            result = sb.toString();


            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024000000];
            int length;
            int flag = 0;
            while ((length = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, length);
                flag++;
            }
            System.out.println("-------------------读取数据次数： " + flag);
            result = byteArrayOutputStream.toString("UTF-8");
            byteArrayOutputStream.close();


//            result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
//            return result;


        } catch (Exception e)
        {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
                if (conn != null)
                {
                    conn.disconnect();
                }
            } catch (IOException ex)
            {
                ex.printStackTrace();
            }
        }

        return result;
    }

    /**
     * post请求，参数放body里，请求参数，请求参数格式 name1=value1&name2=value2 的形式。
     * @param url
     * @param data
     * NameValuePair[] data = {
     *                 new NameValuePair("grant_type", "client_credentials"),
     *                 new NameValuePair("client_id", "99908427"),
     *                 new NameValuePair("client_secret", "49711ac024aa8fe66129eb248c549bf8")
     *
     *         };
     * @return
     */
    public static String sendPostParamToBody(String url, NameValuePair[] data)
    {
        try
        {
            PostMethod postMethod = null;
            postMethod = new PostMethod(url);
            postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

            postMethod.setRequestBody(data);

            HttpClient httpClient = new HttpClient();
            int response = httpClient.executeMethod(postMethod); // 执行POST方法
            String result = postMethod.getResponseBodyAsString();

            return result;
        } catch (Exception e)
        {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * MAP 转 string(key=value&key2=value2...)
     * @param params
     * @return
     */
    public static String mapToString(Map<String, Object> params)
    {
        Map<String,Object> treeMap = new TreeMap<String, Object>(params);
        String result = "";

        Iterator<Map.Entry<String, Object>> it = treeMap.entrySet().iterator();
        while(it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();

            if("".equals(result))
            {
                result = result + entry.getKey() + "=" + entry.getValue();
                continue;
            }
            result =  result+ "&" + entry.getKey() + "=" + entry.getValue();

        }
        return result;
    }

    public static void main(String[] args)
    {
        //发送 GET 请求
//        String s=HttpUtils.sendGet("http://www.weather.com.cn/data/cityinfo/101020100.html", "key=123&v=456");
//        String s=HttpUtils.sendGet("http://restapi.amap.com/v3/weather/weatherInfo", "key=eda593da9359d2b685dc3b3816d8d202&city=310101");
//
//        JSONObject jsonObj = JSONObject.parseObject(s);
//        JSONArray lives = (JSONArray)jsonObj.get("lives");
//
//        Weather weather = (Weather)JSONObject.toJavaObject((JSONObject)lives.get(0), Weather.class);
//        System.out.println(weather.toString());


        //发送 POST 请求
//        String sr=HttpUtils.sendPost("http://www.weather.com.cn/data/sk/101020100.html", "");
//        System.out.println(sr);

        String ss = HttpUtils.sendPost("http://www.dianping.com/shop/98404057", "");
        String s2 = HttpUtils.sendGet("https://www.meituan.com/jiudian/177721470/", "");

        System.out.println(s2);
    }
}
